﻿using System;
using XcoAppSpaces.Core;
using XcoAppSpaces.Core.Ports;
using System.Threading;
using NUnit.Framework;
using XcoAppSpaces.Core.Ports.Remoting;

namespace test.XcoAppSpaces.Core
{
	[TestFixture]
	public class testMessageContext
	{
		[Test]
		public void TestMessageContext_Remote()
		{
			TestMessageContext_Remote(false);
		}

		[Test]
		public void TestMessageContext_RemoteWithCausality()
		{
			TestMessageContext_Remote(true);
		}

		private void TestMessageContext_Remote(bool withCausality)
		{
			using (XcoAppSpace space1 = new XcoAppSpace("tcp.port=8000;tcp.name=myservicename"),
				space2 = new XcoAppSpace("tcp.port=8001"))
			{
				MessageContext context = null;

				var port = new Port<int>();
				space1.RunWorker(port);
				port.RegisterReceiver(msg => context = MessageContext.Current);
                var remotePort = space2.ConnectWorker<Port<int>>(Environment.MachineName + ":8000");
				
				if (withCausality)
					remotePort.Send(1, new Port<Exception>());
				else
					remotePort.Send(1);
				Thread.Sleep(100);

				Assert.IsNotNull(context);
				Assert.IsTrue(context.IsRemoteMessage);
				Assert.IsTrue(context.RemoteAddress.Equals(Environment.MachineName + ":8001", StringComparison.OrdinalIgnoreCase));
				Assert.IsNull(context.Username);
				Assert.AreEqual("myservicename", context.TransportServiceName);
			}
		}

		[Test]
		public void TestMessageContext_Local()
		{
			using (XcoAppSpace space1 = new XcoAppSpace())
			{
				MessageContext context = null;

				var port = new Port<int>();
				space1.RunWorker(port);
				port.RegisterReceiver(msg => context = MessageContext.Current);
				
				port.Post(1);
				Thread.Sleep(100);

				Assert.IsNotNull(context);
				Assert.IsFalse(context.IsRemoteMessage);
				Assert.IsNull(context.RemoteAddress);
				Assert.IsNull(context.TransportServiceName);
				Assert.IsNull(context.Username);
			}
		}
	}
}
